home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / boot / syspred.pl < prev    next >
Encoding:
Text File  |  1997-08-07  |  18.6 KB  |  737 lines

  1. /*  $Id: syspred.pl,v 1.34 1997/08/07 07:57:26 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     jan@swi.psy.uva.nl
  5.  
  6.     Purpose: Prolog system predicate definitions
  7. */
  8.  
  9. :- module($syspreds,
  10.     [ leash/1
  11.     , visible/1
  12.     , style_check/1
  13.     , please/3
  14.     , (spy)/1
  15.     , (nospy)/1
  16.     , trace/1
  17.     , trace/2
  18.     , nospyall/0
  19.     , debugging/0
  20.     , concat_atom/2
  21.     , term_to_atom/2
  22.     , atom_to_term/3
  23.     , int_to_atom/2
  24.     , gensym/2
  25.     , dwim_match/2
  26.     , source_file/1
  27.     , prolog_load_context/2
  28.     , current_predicate/2
  29.     , $defined_predicate/1
  30.     , predicate_property/2
  31.     , $predicate_property/2
  32.     , clause_property/2
  33.     , clause/2
  34.     , clause/3
  35.     , recorda/2
  36.     , recordz/2
  37.     , recorded/2
  38.     , current_module/1
  39.     , current_module/2
  40.     , module/1
  41.     , statistics/0
  42.     , shell/2
  43.     , shell/1
  44.     , shell/0
  45.     , open_shared_object/2
  46.     , open_shared_object/3
  47.     , format/1
  48.     , sformat/2
  49.     , sformat/3
  50.     , garbage_collect/0
  51.     , arithmetic_function/1
  52.         , default_module/2
  53.     , absolute_file_name/2
  54.     , absolute_file_name/3
  55.     , require/1
  56.     , call_with_depth_limit/3
  57.     ]).    
  58.  
  59.         /********************************
  60.         *           DEBUGGER            *
  61.         *********************************/
  62.  
  63. $map_bits(_, [], Bits, Bits) :- !.
  64. $map_bits(Pred, [H|T], Old, New) :-
  65.     $map_bits(Pred, H, Old, New0),
  66.     $map_bits(Pred, T, New0, New).
  67. $map_bits(Pred, +Name, Old, New) :- !,         % set a bit
  68.     call(Pred, Name, Bits), !,
  69.     New is Old \/ Bits.
  70. $map_bits(Pred, -Name, Old, New) :- !,         % clear a bit
  71.     call(Pred, Name, Bits), !,
  72.     New is Old /\ (\Bits).
  73. $map_bits(Pred, ?Name, Old, Old) :-        % ask a bit
  74.     call(Pred, Name, Bits),
  75.     Old /\ Bits > 0.
  76.  
  77. $port_bit(      call, 2'000000001).
  78. $port_bit(      exit, 2'000000010).
  79. $port_bit(      fail, 2'000000100).
  80. $port_bit(      redo, 2'000001000).
  81. $port_bit(     unify, 2'000010000).
  82. $port_bit(     break, 2'000100000).
  83. $port_bit(  cut_call, 2'001000000).
  84. $port_bit(  cut_exit, 2'010000000).
  85. $port_bit( exception, 2'100000000).
  86. $port_bit(       cut, 2'011000000).
  87. $port_bit(       all, 2'000111111).
  88. $port_bit(      full, 2'000101111).
  89. $port_bit(      half, 2'000101101).
  90.  
  91. leash(Ports) :-
  92.     $leash(Old, Old),
  93.     $map_bits($port_bit, Ports, Old, New),
  94.     $leash(_, New).
  95.  
  96. visible(Ports) :-
  97.     $visible(Old, Old),
  98.     $map_bits($port_bit, Ports, Old, New),
  99.     $visible(_, New).
  100.  
  101. $map_style_check(atom,             2'0000001).
  102. $map_style_check(singleton,         2'0000010).
  103. $map_style_check(dollar,           2'0000100).
  104. $map_style_check((discontiguous),   2'0001000).
  105. $map_style_check(string,        2'0010000).
  106. $map_style_check(dynamic,        2'0100000).
  107.  
  108. style_check(Spec) :-
  109.     $style_check(Old, Old),
  110.     $map_bits($map_style_check, Spec, Old, New),
  111.     $style_check(_, New).
  112.  
  113. please(autoload, Old, New) :- !,
  114.     flag($enable_autoload, Old, New).
  115. please(verbose_autoload, Old, New) :- !,
  116.     flag($verbose_autoload, Old, New).
  117. please(Key, Old, New) :-
  118.     $please(Key, Old, New).
  119.  
  120. :- module_transparent
  121.     trace/1,
  122.     trace/2,
  123.     $trace/2,
  124.     spy/1,
  125.     nospy/1.
  126.  
  127. trace(Preds) :-
  128.     trace(Preds, +all).
  129.  
  130. trace([], _) :- !.
  131. trace([H|T], Ps) :- !,
  132.     trace(H, Ps),
  133.     trace(T, Ps).
  134. trace(Pred, Ports) :-
  135.     debug,
  136.     $find_predicate(Pred, Preds),
  137.     Preds \== [],
  138.     (   member(Head, Preds),
  139.         $define_predicate(Head),
  140.             $trace(Ports, Head),
  141.             show_trace_point(Head),
  142.         fail
  143.     ;   true
  144.     ).
  145.  
  146.  
  147. trace_alias(all,  [trace_call, trace_redo, trace_exit, trace_fail]).
  148. trace_alias(call, [trace_call]).
  149. trace_alias(redo, [trace_redo]).
  150. trace_alias(exit, [trace_exit]).
  151. trace_alias(fail, [trace_fail]).
  152.  
  153. $trace([], _) :- !.
  154. $trace([H|T], Head) :- !,
  155.     $trace(H, Head),
  156.     $trace(T, Head).
  157. $trace(+H, Head) :-
  158.     trace_alias(H, A0), !,
  159.     tag_list(A0, +, A1),
  160.     $trace(A1, Head).
  161. $trace(+H, Head) :- !,
  162.     trace_alias(_, [H]),
  163.     $set_predicate_attribute(Head, H, 1).
  164. $trace(-H, Head) :-
  165.     trace_alias(H, A0), !,
  166.     tag_list(A0, -, A1),
  167.     $trace(A1, Head).
  168. $trace(-H, Head) :- !,
  169.     trace_alias(_, [H]),
  170.     $set_predicate_attribute(Head, H, 0).
  171. $trace(H, Head) :-
  172.     atom(H),
  173.     $trace(+H, Head).
  174.  
  175. tag_list([], _, []).
  176. tag_list([H0|T0], F, [H1|T1]) :-
  177.     H1 =.. [F, H0],
  178.     tag_list(T0, F, T1).
  179.  
  180.  
  181. spy([]) :- !.
  182. spy([H|T]) :- !,
  183.     spy(H),
  184.     spy(T).
  185. spy(Spec) :-
  186.     $find_predicate(Spec, Preds),
  187.     member(Head, Preds),
  188.         $define_predicate(Head),
  189.         $spy(Head),
  190.         $predicate_name(Head, Name),
  191.         $ttyformat('Spy point on ~w~n', [Name]),
  192.     fail.
  193. spy(_).
  194.  
  195. nospy([]) :- !.
  196. nospy([H|T]) :- !,
  197.     nospy(H),
  198.     nospy(T).
  199. nospy(Spec) :-
  200.     $find_predicate(Spec, Preds),
  201.     member(Head, Preds),
  202.         $nospy(Head),
  203.         $predicate_name(Head, Name),
  204.         $ttyformat('Spy point removed from ~w~n', [Name]),
  205.     fail.
  206. nospy(_).
  207.  
  208. nospyall :-
  209.     current_predicate(_, Module:Head),
  210.         $nospy(Module:Head),
  211.     fail.
  212. nospyall.
  213.  
  214. debugging :-
  215.     $debugging, !,
  216.     format('Debug mode is on; spy points (see spy/1) on:~n'),
  217.     $show_spy_points,
  218.     format('Trace points (see trace/1) on:~n'),
  219.     show_trace_points.
  220.  
  221. debugging :-
  222.     format('Debug mode is off~n').
  223.  
  224. $show_spy_points :-
  225.     current_predicate(_, Module:Head),
  226.     $get_predicate_attribute(Module:Head, spy, 1),
  227.     \+ predicate_property(Module:Head, imported_from(_)),
  228.     $predicate_name(Module:Head, Name),
  229.     format('~t~8|~w~n', [Name]),
  230.     fail.
  231. $show_spy_points.
  232.  
  233. show_trace_points :-
  234.     current_predicate(_, Module:Head),
  235.     $get_predicate_attribute(Module:Head, trace_any, 1),
  236.     \+ predicate_property(Module:Head, imported_from(_)),
  237.     show_trace_point(Module:Head),
  238.     fail.
  239. show_trace_points.
  240.  
  241. :- module_transparent
  242.     show_trace_point/1,
  243.     show_trace_ports/1.
  244.  
  245. show_trace_point(Head) :-
  246.     $predicate_name(Head, Name),
  247.     format('~t~8|~w:', [Name]),
  248.     show_trace_ports(Head),
  249.     nl.
  250.  
  251. show_trace_ports(Head) :-
  252.     trace_alias(Port, [AttName]),
  253.     $get_predicate_attribute(Head, AttName, 1),
  254.     format(' ~w', [Port]),
  255.     fail.
  256. show_trace_ports(_).
  257.  
  258.  
  259.         /********************************
  260.         *             ATOMS             *
  261.         *********************************/
  262.  
  263. concat_atom([A, B], C) :- !,
  264.     concat(A, B, C).
  265. concat_atom(L, Atom) :-
  266.     $concat_atom(L, Atom).
  267.  
  268. term_to_atom(Term, Atom) :-
  269.     $term_to_atom(Term, Atom, 0, 0).
  270.  
  271. atom_to_term(Atom, Term, Bindings) :-
  272.     $term_to_atom(Term, Atom, B0, 0),
  273.     Bindings = B0.
  274.  
  275. int_to_atom(Int, Atom) :-
  276.     int_to_atom(Int, 10, Atom).
  277.  
  278. gensym(Base, Atom) :-
  279.     concat($gs_, Base, Key),
  280.     flag(Key, Old, Old),
  281.     succ(Old, New),
  282.     flag(Key, _, New),
  283.     concat(Base, New, Atom).
  284.  
  285. dwim_match(A1, A2) :-
  286.     dwim_match(A1, A2, _).
  287.  
  288.         /********************************
  289.         *             SOURCE            *
  290.         *********************************/
  291.  
  292. source_file(File) :-
  293.     $time_source_file(File, _).
  294. source_file(File) :-
  295.     atom(File),
  296.     absolute_file_name(File, Abs),    % canonise
  297.     $time_source_file(Abs, _).
  298.  
  299. %    prolog_load_context(+Key, -Value)
  300. %
  301. %    Provides context information for term_expansion and directives.
  302. %    Note that only the line-number info is valid for the
  303. %    '$stream_position'.  Largely Quintus compatible.
  304.  
  305. :- module_transparent
  306.     prolog_load_context/2.
  307.  
  308. prolog_load_context(module, Module) :-
  309.     $set_source_module(Module, Module).
  310. prolog_load_context(file, F) :-
  311.     source_location(F, _).
  312. prolog_load_context(stream, S) :-
  313.     current_input(S).
  314. prolog_load_context(directory, D) :-
  315.     source_location(F, _),
  316.     file_directory_name(F, D).
  317. prolog_load_context(term_position, '$stream_position'(0,L,0,0,0)) :-
  318.     source_location(_, L).
  319.  
  320.          /*******************************
  321.          *          CONTROL        *
  322.          *******************************/
  323.  
  324. %    call_with_depth_limit(+Goal, +DepthLimit, -Result)
  325. %
  326. %    Try to proof Goal, but fail on any branch exceeding the indicated
  327. %    depth-limit.  Unify Result with the maximum-reached limit on success,
  328. %    depth_limit_exceeded if the limit was exceeded and fails otherwise.
  329.  
  330. :- module_transparent call_with_depth_limit/3.
  331.  
  332. call_with_depth_limit(G, Limit, Result) :-
  333.     $depth_limit(Limit, OLimit, OReached),
  334.     (   G,
  335.         $depth_limit_true(Limit, OLimit, OReached, Result, Cut),
  336.         Cut
  337.     ;   $depth_limit_false(Limit, OLimit, OReached, Result)
  338.     ).
  339.  
  340.  
  341.         /********************************
  342.         *           DATA BASE           *
  343.         *********************************/
  344.  
  345. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  346. The predicate current_predicate/2 is   a  difficult subject since  the
  347. introduction  of defaulting     modules   and   dynamic     libraries.
  348. current_predicate/2 is normally  called with instantiated arguments to
  349. verify some  predicate can   be called without trapping   an undefined
  350. predicate.  In this case we must  perform the search algorithm used by
  351. the prolog system itself.
  352.  
  353. If the pattern is not fully specified, we only generate the predicates
  354. actually available in this  module.   This seems the best for listing,
  355. etc.
  356. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  357.  
  358.  
  359. :- module_transparent
  360.     current_predicate/2,
  361.     $defined_predicate/1.
  362.  
  363. current_predicate(Name, Head) :-
  364.     var(Head), !,
  365.     context_module(Module),
  366.     generate_current_predicate(Name, Module, Head).
  367. current_predicate(Name, Module:Head) :-
  368.     (var(Module) ; var(Head)), !,
  369.     generate_current_predicate(Name, Module, Head).
  370. current_predicate(Name, Term) :-
  371.     $c_current_predicate(Name, Term),
  372.     $defined_predicate(Term), !.
  373. current_predicate(Name, Term) :-
  374.     $strip_module(Term, Module, Head),
  375.     default_module(Module, DefModule),
  376.     $c_current_predicate(Name, DefModule:Head),
  377.     $defined_predicate(DefModule:Head), !.
  378. current_predicate(Name, Term) :-
  379.     flag($enable_autoload, on, on),
  380.     $strip_module(Term, Module, Head),
  381.     functor(Head, Name, Arity),
  382.     $find_library(Module, Name, Arity, _LoadModule, _Library), !.
  383.  
  384. generate_current_predicate(Name, Module, Head) :-
  385.     current_module(Module),
  386.     $c_current_predicate(Name, Module:Head),
  387.     $defined_predicate(Module:Head).
  388.  
  389. $defined_predicate(Head) :-
  390.     $get_predicate_attribute(Head, defined, 1), !.
  391.  
  392. :- module_transparent
  393.     predicate_property/2,
  394.     $predicate_property/2.
  395.  
  396. predicate_property(Pred, Property) :-
  397.     Property == undefined, !,
  398.     (   Pred = Module:Head,
  399.         var(Module)
  400.     ;   $strip_module(Pred, Module, Head)
  401.     ), !,
  402.     current_module(Module),
  403.     Term = Module:Head,
  404.     $c_current_predicate(_, Term),
  405.     \+ $defined_predicate(Term),        % Speed up a bit
  406.     \+ current_predicate(_, Term).
  407. predicate_property(Pred, Property) :-
  408.     current_predicate(_, Pred),
  409.     $predicate_property(Property, Pred).
  410.  
  411. $predicate_property(interpreted, Pred) :-
  412.     $get_predicate_attribute(Pred, foreign, 0).
  413. $predicate_property(built_in, Pred) :-
  414.     $get_predicate_attribute(Pred, system, 1).
  415. $predicate_property(exported, Pred) :-
  416.     $get_predicate_attribute(Pred, exported, 1).
  417. $predicate_property(foreign, Pred) :-
  418.     $get_predicate_attribute(Pred, foreign, 1).
  419. $predicate_property((dynamic), Pred) :-
  420.     $get_predicate_attribute(Pred, (dynamic), 1).
  421. $predicate_property((volatile), Pred) :-
  422.     $get_predicate_attribute(Pred, (volatile), 1).
  423. $predicate_property((multifile), Pred) :-
  424.     $get_predicate_attribute(Pred, (multifile), 1).
  425. $predicate_property(imported_from(Module), Pred) :-
  426.     $get_predicate_attribute(Pred, imported, Module).
  427. $predicate_property(transparent, Pred) :-
  428.     $get_predicate_attribute(Pred, transparent, 1).
  429. $predicate_property(indexed(Pattern), Pred) :-
  430.     $get_predicate_attribute(Pred, indexed, Pattern).
  431. $predicate_property(file(File), Pred) :-
  432.     source_file(Pred, File).
  433. $predicate_property(line_count(LineNumber), Pred) :-
  434.     $get_predicate_attribute(Pred, line_count, LineNumber).
  435. $predicate_property(notrace, Pred) :-
  436.     $get_predicate_attribute(Pred, trace, 0).
  437. $predicate_property(show_childs, Pred) :-
  438.     $get_predicate_attribute(Pred, system, 1),
  439.     $get_predicate_attribute(Pred, hide_childs, 0).
  440. $predicate_property(hashed(N), Pred) :-
  441.     $get_predicate_attribute(Pred, hashed, N),
  442.     N > 0.
  443. $predicate_property(references(N), Pred) :-
  444.     $get_predicate_attribute(Pred, references, N),
  445.     N > 0.
  446. $predicate_property(number_of_clauses(N), Pred) :-
  447.     $get_predicate_attribute(Pred, number_of_clauses, N),
  448.     N > 0.
  449.  
  450. :- index(clause_property(0, 1)).
  451.  
  452. clause_property(Clause, line_count(LineNumber)) :-
  453.     $get_clause_attribute(Clause, line_count, LineNumber).
  454. clause_property(Clause, file(File)) :-
  455.     $get_clause_attribute(Clause, file, File).
  456. clause_property(Clause, fact) :-
  457.     $get_clause_attribute(Clause, fact, true).
  458. clause_property(Clause, erased) :-
  459.     $get_clause_attribute(Clause, erased, true).
  460.  
  461.  
  462. :- module_transparent
  463.     clause/2,
  464.     clause/3.
  465.  
  466. clause(Head, Body, Ref) :-
  467.     nonvar(Ref), !,
  468.     $clause(Head, Clause, Ref),
  469.     $strip_module(Head, _, H),
  470.     $clause2(H, Body, Clause).
  471. clause(Head, Body, Ref) :-
  472.     current_predicate(_, Head),
  473.     $clause(Head, Clause, Ref),
  474.     $strip_module(Head, _, H),
  475.     $clause2(H, Body, Clause).
  476.  
  477. clause(Head, Body) :-
  478.     current_predicate(_, Head),
  479.     $clause(Head, Clause, _),
  480.     $strip_module(Head, _, H),
  481.     $clause2(H, Body, Clause).
  482.  
  483. $clause2(Head, Body, (Head :- Body)) :- !.
  484. $clause2(Head, true, Head).
  485.  
  486. recorda(Key, Value) :-
  487.     recorda(Key, Value, _).
  488. recordz(Key, Value) :-
  489.     recordz(Key, Value, _).
  490. recorded(Key, Value) :-
  491.     recorded(Key, Value, _).
  492.  
  493.          /*******************************
  494.          *           REQUIRE        *
  495.          *******************************/
  496.  
  497. :- module_transparent
  498.     require/1.
  499.  
  500. require([]).
  501. require([N/A|T]) :- !,
  502.     functor(Head, N, A),
  503.     $require(Head),
  504.     require(T).
  505. require([H|T]) :-
  506.     $warning('require/1: Illegal predicate specifier: ~w', [H]),
  507.     require(T).
  508.  
  509.         /********************************
  510.         *            MODULES            *
  511.         *********************************/
  512.  
  513. current_module(Module) :-
  514.     $current_module(Module, _).
  515.  
  516. current_module(Module, File) :-
  517.     $current_module(Module, File),
  518.     File \== [].
  519.  
  520. module(Module) :-
  521.     atom(Module),
  522.     current_module(Module), !,
  523.     $module(_, Module).
  524. module(Module) :-
  525.     $break($warning('~w is not a current module', [Module])),
  526.     $module(_, Module).
  527.  
  528.         /********************************
  529.         *          STATISTICS           *
  530.         *********************************/
  531.  
  532. statistics :-
  533.     statistics(trail, Trail),
  534.     statistics(trailused, TrailUsed),
  535.     statistics(local, Local),
  536.     statistics(localused, LocalUsed),
  537.     statistics(global, Global),
  538.     statistics(globalused, GlobalUsed),
  539.     statistics(cputime, Cputime),
  540.     statistics(inferences, Inferences),
  541.     statistics(heapused, Heapused),
  542.     statistics(atoms, Atoms),
  543.     statistics(functors, Functors),
  544.     statistics(predicates, Predicates),
  545.     statistics(modules, Modules),
  546.     statistics(codes, Codes),
  547.     statistics(locallimit, LocalLimit),
  548.     statistics(globallimit, GlobalLimit),
  549.     statistics(traillimit, TrailLimit),
  550.  
  551.     format('~2f seconds cpu time for ~D inferences~n',
  552.                     [Cputime, Inferences]),
  553.     format('~D atoms, ~D functors, ~D predicates, ~D modules, ~D VM-codes~n~n',
  554.                     [Atoms, Functors, Predicates, Modules, Codes]),
  555.     format('                       Limit    Allocated       In use~n'),
  556.     (   statistics(heap, Heap),
  557.         statistics(heaplimit, HeapLimit)
  558.     ->  format('Heap         :~t~D~28| ~t~D~41| ~t~D~54| Bytes~n',
  559.            [HeapLimit, Heap, Heapused])
  560.     ;   format('Heap         :                  ~t~D~54| Bytes~n',
  561.            [Heapused])
  562.     ),
  563.     format('Local  stack :~t~D~28| ~t~D~41| ~t~D~54| Bytes~n',
  564.            [LocalLimit, Local, LocalUsed]),
  565.     format('Global stack :~t~D~28| ~t~D~41| ~t~D~54| Bytes~n',
  566.            [GlobalLimit, Global, GlobalUsed]),
  567.     format('Trail  stack :~t~D~28| ~t~D~41| ~t~D~54| Bytes~n',
  568.            [TrailLimit, Trail, TrailUsed]),
  569.  
  570.     gc_statistics,
  571.     shift_statistics.
  572.  
  573. gc_statistics :-
  574.     statistics(collections, Collections),
  575.     Collections > 0, !,
  576.     statistics(collected, Collected),
  577.     statistics(gctime, GcTime),
  578.  
  579.     format('~n~D garbage collections gained ~D bytes in ~2f seconds.~n',
  580.            [Collections, Collected, GcTime]).
  581. gc_statistics.
  582.  
  583. shift_statistics :-
  584.     statistics(local_shifts, LS),
  585.     statistics(global_shifts, GS),
  586.     statistics(trail_shifts, TS),
  587.     (   LS > 0
  588.     ;   GS > 0
  589.     ;   TS > 0
  590.     ), !,
  591.     format('~nStack shifts: ~D local, ~D global, ~D trail.~n',
  592.            [LS, GS, TS]).
  593. shift_statistics.
  594.  
  595.  
  596.         /********************************
  597.         *      SYSTEM INTERACTION       *
  598.         *********************************/
  599.  
  600. shell(Command, Status) :-
  601.     $shell(Command, Status).
  602.  
  603. shell(Command) :-
  604.     shell(Command, 0).
  605.  
  606. shell :-
  607.     getenv('SHELL', Shell), !,
  608.     shell(Shell).
  609. shell :-
  610.     shell('/bin/sh').
  611.  
  612.  
  613.          /*******************************
  614.          *          DLOPEN        *
  615.          *******************************/
  616.  
  617. dlopen_flag(now,    2'01).        % see pl-load.c for these constants
  618. dlopen_flag(global,    2'10).        % Solaris only
  619.  
  620. map_dlflags([], 0).
  621. map_dlflags([F|T], M) :-
  622.     map_dlflags(T, M0),
  623.     dlopen_flag(F, I),
  624.     M is M0 \/ I.
  625.  
  626. open_shared_object(File, Flags, Handle) :-
  627.     map_dlflags(Flags, Mask),
  628.     $open_shared_object(File, Handle, Mask).
  629.  
  630. open_shared_object(File, Handle) :-
  631.     open_shared_object(File, [global], Handle). % use pl-load.c defaults
  632.  
  633.  
  634.         /********************************
  635.         *              I/O              *
  636.         *********************************/
  637.  
  638. format(Fmt) :-
  639.     format(Fmt, []).
  640.  
  641. sformat(String, Format, Arguments) :-
  642.     $write_on_string(format(Format, Arguments), String).
  643. sformat(String, Format) :-
  644.     $write_on_string(format(Format), String).
  645.  
  646.          /*******************************
  647.          *          FILES        *
  648.          *******************************/
  649.  
  650. %    absolute_file_name(+Term, +Args, -AbsoluteFile)
  651.  
  652. absolute_file_name(Spec, Args, Path) :-
  653.     (   select(Args, extensions(Exts), Conditions)
  654.     ->  true
  655.     ;   select(Args, file_type(Type), Rest)
  656.     ->  file_type_conditions(Type, Exts, C0),
  657.         append(C0, Rest, Conditions)
  658.     ;   Conditions = Args,
  659.         Exts = ['']
  660.     ),
  661.     (   select(Conditions, solutions(Sols), C1)
  662.     ->  true
  663.     ;   Sols = first,
  664.         C1 = Conditions
  665.     ),
  666.     (   select(C1, file_errors(FileErrors), C2)
  667.     ->  true
  668.     ;   FileErrors = fail,
  669.         C2 = C1
  670.     ),
  671.     (   $chk_file(Spec, Exts, C2, Path)
  672.     ->  (   Sols == first
  673.         ->  !
  674.         ;   true
  675.         )
  676.     ;   (   FileErrors == fail
  677.         ->  fail
  678.         ;   $warning('~w: No such file or directory', Spec),
  679.         fail
  680.         )
  681.     ).
  682.  
  683. file_type_conditions(txt,        [''],        []).
  684. file_type_conditions(prolog,     ['.pl', ''],    []).
  685. file_type_conditions(executable, ['.so', ''],    []).
  686. file_type_conditions(qlf,      ['.qlf', ''],    []).
  687. file_type_conditions(directory,  [''],        []).
  688.  
  689. %    absolute_file_name(+Term, -AbsoluteFile)
  690.  
  691. absolute_file_name(Name, Abs) :-
  692.     atomic(Name), !,
  693.     $absolute_file_name(Name, Abs).
  694. absolute_file_name(Term, Abs) :-
  695.     $chk_file(Term, [''], [access(read)], File), !,
  696.     $absolute_file_name(File, Abs).
  697. absolute_file_name(Term, Abs) :-
  698.     $chk_file(Term, [''], [], File), !,
  699.     $absolute_file_name(File, Abs).
  700.  
  701.  
  702.         /********************************
  703.         *         MISCELLENEOUS         *
  704.         *********************************/
  705.  
  706. %    Invoke the garbage collector.  The argument is the debugging level
  707. %    to use during garbage collection.  This only works if the system
  708. %    is compiled with the -DODEBUG cpp flag.  Only to simplify maintenance.
  709.  
  710. garbage_collect :-
  711.     $garbage_collect(0).
  712.  
  713. %    arithmetic_function(Spec)
  714. %    Register a predicate as an arithmetic function.  Takes Name/Arity
  715. %    and a term as argument.
  716.  
  717. :- module_transparent
  718.     arithmetic_function/1.
  719.  
  720. arithmetic_function(Spec) :-
  721.     $strip_module(Spec, Module, Term),
  722.     (   Term = Name/Arity
  723.     ;   functor(Term, Name, Arity)
  724.     ), !,
  725.     PredArity is Arity + 1,
  726.     functor(Head, Name, PredArity),
  727.     $arithmetic_function(Module:Head).
  728.  
  729. %    default_module(+Me, -Super)
  730. %    Is true if `Super' is `Me' or a super (auto import) module of `Me'.
  731.  
  732. default_module(Me, Me).
  733. default_module(Me, Super) :-
  734.     $default_module(Me, S, S),
  735.     S \== [],
  736.     default_module(S, Super).
  737.